package me.xlgp.xiquzimu.util;

import com.github.promeg.pinyinhelper.Pinyin;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import me.xlgp.xiquzimu.EmojiManager;
import me.xlgp.xiquzimu.constant.LycConstant;
import me.xlgp.xiquzimu.model.ChangCi;
import me.xlgp.xiquzimu.model.ChangCiList;
import me.xlgp.xiquzimu.model.ChangDuan;
import me.xlgp.xiquzimu.model.ChangDuanInfo;
import me.xlgp.xiquzimu.params.LeftChangDuan;
import me.xlgp.xiquzimu.params.TagChangDuan;
import me.xlgp.xiquzimu.service.DouYinAccessibilityService;

public class ChangDuanHelper {

    public static StringBuilder copyFromChangDuanInfo(ChangDuanInfo ziMuInfo) {

        ChangDuan changDuan = ziMuInfo.getChangDuan();
        StringBuilder text = new StringBuilder();
        text.append("[ti:").append(changDuan.getName()).append("]").append("\n");
        text.append("[jz:").append(changDuan.getJuZhong()).append("]").append("\n");
        text.append("[jm:").append(changDuan.getJuMu()).append("]").append("\n");
        text.append("[offset:").append(changDuan.getOffset()).append("]").append("\n");

        List<ChangCi> changCiList = ziMuInfo.getChangCiList();

        for (ChangCi changci : changCiList) {
            text.append("[").append(changci.getShowTime()).append("]").append(changci.getContent()).append("\n");
        }

        return text;
    }

    public static StringBuilder copyChunJingFromChangDuanInfo(ChangDuanInfo ziMuInfo) {

        ChangDuan changDuan = ziMuInfo.getChangDuan();
        StringBuilder text = new StringBuilder();
        text.append(changDuan.getName()).append("\n");
        text.append(changDuan.getJuZhong()).append("\n");
        text.append(changDuan.getJuMu()).append("\n");

        List<ChangCi> changCiList = ziMuInfo.getChangCiList();

        for (ChangCi changci : changCiList) {
            text.append(changci.getContent()).append("\n");
        }

        return text;

    }

    public static List<LeftChangDuan> setLeftChangDuan(List<ChangDuan> list) {
        List<LeftChangDuan> leftchangDuanList = new ArrayList<>();
        String name = "";
        for (int i = 0; i < list.size(); i++) {
            ChangDuan changDuan = list.get(i);
            if (!name.equals(changDuan.getJuMu())) {
                LeftChangDuan leftchangDuan = new LeftChangDuan();
                leftchangDuan.setName(changDuan.getJuMu());
                leftchangDuan.setId(i);
                name = changDuan.getJuMu();
                leftchangDuanList.add(leftchangDuan);
            }
        }
        return leftchangDuanList;
    }

    public static List<TagChangDuan> getTagChangDuan(List<ChangDuan> list) {
        List<TagChangDuan> tagchangDuanList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            ChangDuan changDuan = list.get(i);
            TagChangDuan tagChangDuan = new TagChangDuan();
            tagChangDuan.setId(changDuan.getId());
            tagChangDuan.setName(changDuan.getName());
            tagChangDuan.setOffset(changDuan.getOffset());
            tagChangDuan.setJuMu(changDuan.getJuMu());
            tagChangDuan.setJuZhong(changDuan.getJuZhong());
            tagChangDuan.setTag(String.valueOf(Pinyin.toPinyin(changDuan.getJuMu().charAt(0)).charAt(0)));
            tagChangDuan.setCreateTime(changDuan.getCreateTime());
            tagchangDuanList.add(tagChangDuan);
        }
        return tagchangDuanList;
    }

    private static ChangCi getBeforeChangCi(ChangDuan changDuan) {
        ChangCi preChangCi = new ChangCi();
        preChangCi.setDelayMillis(1000);
        preChangCi.setShowTime(formatDate("00:00.00", 1000));
        preChangCi.setContent(EmojiManager.SMALL_BLUE_DIAMOND + "请欣赏" + EmojiManager.SPARKLES + changDuan.getJuZhong() + "《" + changDuan.getJuMu() + "》" + "选段：" + changDuan.getName());
        return preChangCi;
    }

    /**
     * 添加字幕前后缀
     */
    private static void addBeforeChangCi(ChangDuan changDuan, List<ChangCi> changCiList) {
        changCiList.add(0, getBeforeChangCi(changDuan));
    }

    private static String formatDate(String strDate, long delayMillis) {
        SimpleDateFormat format = new SimpleDateFormat("mm:ss.SS", Locale.CHINESE);
        try {
            long result = Objects.requireNonNull(format.parse(strDate)).getTime() + delayMillis;
            Date date = new Date();
            date.setTime(result);
            return format.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strDate;
    }

    private static ChangCi getChangCi(String content, long delayMillis, String lastShowTime) {
        ChangCi changCi = new ChangCi();
        changCi.setDelayMillis(delayMillis);
        changCi.setShowTime(formatDate(lastShowTime, delayMillis));
        changCi.setContent(content);
        return changCi;
    }

    /**
     * 主要用于对面主播
     *
     * @param showTime
     * @return
     */
    private static ChangCi getZhuFuCi(String showTime) {
        //祝福词
        DouYinAccessibilityService service = DouYinAccessibilityService.getInstance();
        if (service == null) return null;
        String userName = service.getUserName();
        if (userName == null) return null;
        return getChangCi(EmojiManager.SMALL_BLUE_DIAMOND + "祝主播一路长虹", 2000, showTime);
    }

    /**
     * 给对面发送字幕时，对自己主播的简介
     *
     * @return
     */
    private static ChangCi getZhuBoJiaoJie(String showTime) {
        //主播简介
        DouYinAccessibilityService service = DouYinAccessibilityService.getInstance();
        if (service == null) return null;
        String userName = service.getAnotherUserName();
        if (userName == null) return null;
        return getChangCi(EmojiManager.SMALL_BLUE_DIAMOND + "演唱者: " + userName, 3000, showTime);
    }

    private static void addAfterChangCi(ChangDuan changDuan, List<ChangCi> changCiList) {
        //唱段简介
        changCiList.add(getChangCi(EmojiManager.SMALL_BLUE_DIAMOND + "本曲出自" + changDuan.getJuZhong() + "《" + changDuan.getJuMu() + "》选段：" + changDuan.getName(),
                15000,
                changCiList.get(changCiList.size() - 1).getShowTime()));
        //感谢词
        changCiList.add(getChangCi(EmojiManager.SMALL_BLUE_DIAMOND + "谢谢各位聆听", 3000, changCiList.get(changCiList.size() - 1).getShowTime()));

        //祝福词
        changCiList.add(getChangCi(EmojiManager.SMALL_BLUE_DIAMOND + "祝主播一路长虹", 2000, changCiList.get(changCiList.size() - 1).getShowTime()));
    }

    public static void addFullChangCiList(ChangDuan changDuan, List<ChangCi> changCiList) {

        for (int i = 0; i < changCiList.size(); i++) {
            changCiList.get(i).setContent(EmojiManager.SMALL_BLUE_DIAMOND + changCiList.get(i).getContent());
        }
        addBeforeChangCi(changDuan, changCiList);
        addAfterChangCi(changDuan, changCiList);
    }

    public static ChangCiList parseChangCiList(ChangDuan changDuan, List<ChangCi> changCis) {
        addFullChangCiList(changDuan, changCis);
        ChangCiList changCiList = new ChangCiList();
        changCiList.addAll(changCis);
        return changCiList;
    }

    public static void parseChangCiListByDelayMillis(ChangDuanInfo changDuanInfo) throws Exception {
        List<ChangCi> changCiList = changDuanInfo.getChangCiList();
        long beforeMillis = getDelayMillis("00:00.00");
        long offset = changDuanInfo.getChangDuan().getOffset() * 1000;
        try { //此处之所以try catch 是因为getDelayMillis在for循环内，
            // 若不try catch 直接抛异常的话，getDelayMillis抛异常后for会继续执行，不会跳出。
            for (int i = 0; i < changCiList.size(); i++) {
                //当前的时间的毫秒
                long curMillis = getDelayMillis(changCiList.get(i).getShowTime());
                //时间间隔 = 本句的时间-前句时间
                long delayMillis = curMillis - beforeMillis;
                if (i == 0 && delayMillis + offset > 0) { //若是第一句，加上时间差值,offset:一般表示唱词先于唱段声音出现
                    delayMillis += offset;
                }
                if (delayMillis < 1000) delayMillis = 1500;
                changCiList.get(i).setDelayMillis(delayMillis);
                beforeMillis = curMillis;
            }
        } catch (ParseException e) {
            throw new Exception(e);
        }
    }

    /**
     * 从存储中或网络中获取lrc文件后，格式化为 ChangDuan对象
     *
     * @param list list
     * @return ChangDuanInfo
     */
    public static ChangDuanInfo parse(List<String> list) throws Exception {
        ChangDuanInfo changDuanInfo = new ChangDuanInfo();
        for (String str : list) {
            String line = str.trim();
            if (matcher(line, LycConstant.TIME_REG)) { //唱词
                ChangCi changCi = getChangCi(line);
                changCi.setOrderId(changDuanInfo.getChangCiList().size() + 1);
                changDuanInfo.getChangCiList().add(changCi);
            } else if (matcher(line, LycConstant.TITLE_REG)) { //名称
                changDuanInfo.getChangDuan().setName(getQitaContent(line, LycConstant.TITLE_START));
            } else if (matcher(line, LycConstant.JUMU_REG)) {
                changDuanInfo.getChangDuan().setJuMu(getQitaContent(line, LycConstant.JUMU_START));
            } else if (matcher(line, LycConstant.OFFSET_REG)) {
                String offset = getQitaContent(line, LycConstant.OFFSET_START);
                changDuanInfo.getChangDuan().setOffset(Integer.parseInt(offset) * 1000);
            } else if (matcher(line, LycConstant.JUZHONG_REG)) {
                changDuanInfo.getChangDuan().setJuZhong(getQitaContent(line, LycConstant.JUZHONG_START));
            } else if (matcher(line, LycConstant.BEIZHU_REG)) {
                changDuanInfo.getChangDuan().setBeiZhu(getQitaContent(line, LycConstant.BEIZHU_START));
            }
        }
        parseChangCiListByDelayMillis(changDuanInfo);
        return changDuanInfo;
    }

    private static String getQitaContent(String line, int beginIndex) {
        return line.substring(beginIndex, line.length() - 1).trim();
    }

    private static ChangCi getChangCi(String line) {
        String[] strings = line.trim().split("]");
        ChangCi changCi = new ChangCi();
        changCi.setContent(strings[strings.length - 1].trim());
        changCi.setShowTime(strings[0].substring(1));
        return changCi;
    }

    private static long getDelayMillis(String time) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("mm:ss.SSS", Locale.CHINESE);
        return Objects.requireNonNull(format.parse(time)).getTime();
    }

    private static boolean matcher(String line, String reg) {
        Pattern p = Pattern.compile(reg);
        Matcher matcher = p.matcher(line);
        return matcher.find();
    }
}
